import java.util.*;
/**
 * Represents one scope in the linked
 * symbol table.
 * @author James Stanier
 */
public class Env {
	private Hashtable<String, Symbol> table;
	private String name;
	protected Env prev;
	private ArrayList<String> symbols;
	
	/**
	 * Constructor.
	 * @param p The previous scope on the table.
	 * @param s Textual description of this scope.
	 */
	public Env(Env p, String s) {
		table = new Hashtable<String, Symbol>();
		symbols = new ArrayList<String>();
		prev = p;
		name = s;
	}
	
	/**
	 * Change the name of this scope.
	 * @param s The new name.
	 */
	public void setName(String s) {
		name = s;
	}
	
	/**
	 * Append the name of this scope.
	 * @param s The name to append.
	 */
	public void appendName(String s) {
		name = name + " " + s;
	}
	
	/**
	 * Get the name of this scope.
	 * @return The name of the scope.
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * Put a symbol in the table.
	 * @param s Variable name.
	 * @param sym Symbol object.
	 */
	public void put(String s, Symbol sym) {
		symbols.add(s);
		table.put(s, sym);
	}
	
	/**
	 * Get a symbol object that matches a String.
	 * @param s The symbol name.
	 * @return The object associated with that name.
	 */
	public Symbol get(String s) {
		for(Env e = this; e != null; e = e.prev) {
			Symbol found = (Symbol)(e.table.get(s));
			if(found != null) {
				return found;
			}
		}
		return null;
	}
	
	/**
	 * Get the size of the table.
	 * @return The size of the table.
	 */
	public int tableSize() {
		return table.size();
	}
	
	/**
	 * Get the hashtable used for storing symbols.
	 * @return The symbol table for this scope.
	 */
	public Hashtable<String, Symbol> getTable() {
		return table;
	}
	
	/**
	 * Get the array of symbol names.
	 * @return The array of symbol names.
	 */
	public ArrayList<String> getSymbols() {
		return symbols;
	}
	
	/**
	 * Output the table to String.
	 * @return String representation of the table.
	 */
	public String dumpThis() {
		return table.toString();
	}
	
	/**
	 * Print the whole table to console.
	 */
	public void dumpAll() {
		for(Env e = this; e != null; e = e.prev) {
			
			table.toString();
		}
	}
}
